﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Rung.Soft.Jx3Tookit.Addon.AutoPress.Utility
{
    public static class Hook
    {
        private static IntPtr _hookID = IntPtr.Zero;
        public static Keys startKillsKey = Keys.V;

        /// <summary>
        /// 安装钩子
        /// </summary>
        public static bool RunHook()
        {
            _hookID = SetHook(HookCallback);

            return _hookID != IntPtr.Zero;
        }

        /// <summary>
        /// 卸载钩子
        /// </summary>
        public static void UnHook()
        {
            Win32API.UnhookWindowsHookEx(_hookID);
        }

        /// <summary>
        /// 安装钩子
        /// </summary>
        /// <param name="proc"></param>
        /// <returns></returns>
        private static IntPtr SetHook(Win32API.LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            {
                using (ProcessModule curModule = curProcess.MainModule)
                {
                    return Win32API.SetWindowsHookEx(Win32API.WH_KEYBOARD_LL, proc, Win32API.GetModuleHandle(curModule.ModuleName), 0);
                }
            }
        }

        /// <summary>
        /// 处理函数
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns>
        /// 如果返回1，则结束消息，这个消息到此为止，不再传递；
        /// 如果返回0或调用CallNextHookEx函数则消息出了这个钩子继续往下传递，也就是传给消息真正的接受者；
        /// </returns>
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            //键盘按下时
            if (nCode >= 0 && wParam == (IntPtr)Win32API.WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                Keys key = (Keys)vkCode;

                if (key == startKillsKey && DoWork != null)
                {
                    DoWork();
                }
            }

            return Win32API.CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        public static MethodInvoker DoWork;
    }
}
